

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- CREATE DATABASE `uuwaf` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE `uuwaf`;
-- ----------------------------
-- Table structure for waf_audits
-- ----------------------------
DROP TABLE IF EXISTS `waf_audits`;
CREATE TABLE `waf_audits` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `type` varchar(16) NOT NULL,
  `info` text NOT NULL,
  `usr` varchar(32) NOT NULL,
  `ip` varchar(64) NOT NULL,
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT;



-- ----------------------------
-- Table structure for waf_cdn
-- ----------------------------
DROP TABLE IF EXISTS `waf_cdn`;
CREATE TABLE `waf_cdn` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT 1,
  `enabled` tinyint(1) NOT NULL DEFAULT 1,
  `host` varchar(64) NOT NULL,
  `uri` text NOT NULL,
  `cache_time` varchar(16) NOT NULL,
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT;

-- ----------------------------
-- Records of waf_cdn
-- ----------------------------
BEGIN;
COMMIT;

-- ----------------------------
-- Table structure for waf_certs
-- ----------------------------
DROP TABLE IF EXISTS `waf_certs`;
CREATE TABLE `waf_certs` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT 1,
  `type` tinyint(4) NOT NULL,
  `name` varchar(64) NOT NULL,
  `email` varchar(64) NOT NULL,
  `sni` text NOT NULL,
  `crt` text NOT NULL,
  `key` text NOT NULL,
  `dns_challenge` tinyint(1) NOT NULL,
  `dns_provider` varchar(64) NOT NULL,
  `dns_credential` text NOT NULL,
  `expired_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT;

-- ----------------------------
-- Records of waf_certs
-- ----------------------------
BEGIN;
INSERT INTO `waf_certs` (`id`, `uid`, `type`, `name`, `email`, `sni`, `crt`, `key`, `dns_challenge`, `dns_provider`, `dns_credential`, `expired_at`, `updated_at`) VALUES (1, 1, 1, 'Default', '', '[\"*.lsmir2.com\"]', '-----BEGIN CERTIFICATE-----\nMIIDhzCCAw2gAwIBAgISBeBeNf4BxH+Lrooe0Q/RjjwxMAoGCCqGSM49BAMDMDIx\nCzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF\nNjAeFw0yNTA2MTkxNTAxNTlaFw0yNTA5MTcxNTAxNThaMBcxFTATBgNVBAMMDCou\nbHNtaXIyLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABCATY21AYyYjaGwS\nUWihgdt2+bnPNznLLaJXGZRFl8pqgj9xI4DFlx82jBfU99e1lW/7gcisxXSCr3Cv\n+u4BL8mjggIcMIICGDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0lBBYwFAYIKwYBBQUH\nAwEGCCsGAQUFBwMCMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFLPBGO4W5oXwzn9C\nsKSJ+6HcNHC7MB8GA1UdIwQYMBaAFJMnRpgDqVFojpjWxEJI2yO/WJTSMDIGCCsG\nAQUFBwEBBCYwJDAiBggrBgEFBQcwAoYWaHR0cDovL2U2LmkubGVuY3Iub3JnLzAX\nBgNVHREEEDAOggwqLmxzbWlyMi5jb20wEwYDVR0gBAwwCjAIBgZngQwBAgEwLQYD\nVR0fBCYwJDAioCCgHoYcaHR0cDovL2U2LmMubGVuY3Iub3JnLzUwLmNybDCCAQYG\nCisGAQQB1nkCBAIEgfcEgfQA8gB3ABLxTjS9U3JMhAYZw48/ehP457Vih4icbTAF\nhOvlhiY6AAABl4jrktsAAAQDAEgwRgIhAPTiiCrxi9I3zoWliGEYrAfmOxQ2dkSb\nHJhgPx+Xx2sZAiEAnUN+UJGDz8gYTy4jtN5+Pe7FKbO430g1ZZ972utpmSAAdwAN\n4fIwK9MNwUBiEgnqVS78R3R8sdfpMO8OQh60fk6qNAAAAZeI65q6AAAEAwBIMEYC\nIQCYZSImhas20ThxgxPtPTSUF4EDR3Vw1mK7VuRku4fCdQIhAOzxAJ8tgNBU/V6h\nIJGKKn5iqDbcZxGhTuIEDTzBCDlMMAoGCCqGSM49BAMDA2gAMGUCMQCB2+wYQfgk\noFX2nFBBcAkwIC3oOl387b7W+34ifP7Z6Lt7mXxgzHp3058ZDsj3qRsCMG7+fSwb\nL3tgu7lwf1Y7WyMRMa49IOrss+wzbRq3Mv/3T1Cr2plFfdHYe5skT25nGQ==\n-----END CERTIFICATE-----\n\n-----BEGIN CERTIFICATE-----\nMIIEVzCCAj+gAwIBAgIRALBXPpFzlydw27SHyzpFKzgwDQYJKoZIhvcNAQELBQAw\nTzELMAkGA1UEBhMCVVMxKTAnBgNVBAoTIEludGVybmV0IFNlY3VyaXR5IFJlc2Vh\ncmNoIEdyb3VwMRUwEwYDVQQDEwxJU1JHIFJvb3QgWDEwHhcNMjQwMzEzMDAwMDAw\nWhcNMjcwMzEyMjM1OTU5WjAyMQswCQYDVQQGEwJVUzEWMBQGA1UEChMNTGV0J3Mg\nRW5jcnlwdDELMAkGA1UEAxMCRTYwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAATZ8Z5G\nh/ghcWCoJuuj+rnq2h25EqfUJtlRFLFhfHWWvyILOR/VvtEKRqotPEoJhC6+QJVV\n6RlAN2Z17TJOdwRJ+HB7wxjnzvdxEP6sdNgA1O1tHHMWMxCcOrLqbGL0vbijgfgw\ngfUwDgYDVR0PAQH/BAQDAgGGMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD\nATASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSTJ0aYA6lRaI6Y1sRCSNsj\nv1iU0jAfBgNVHSMEGDAWgBR5tFnme7bl5AFzgAiIyBpY9umbbjAyBggrBgEFBQcB\nAQQmMCQwIgYIKwYBBQUHMAKGFmh0dHA6Ly94MS5pLmxlbmNyLm9yZy8wEwYDVR0g\nBAwwCjAIBgZngQwBAgEwJwYDVR0fBCAwHjAcoBqgGIYWaHR0cDovL3gxLmMubGVu\nY3Iub3JnLzANBgkqhkiG9w0BAQsFAAOCAgEAfYt7SiA1sgWGCIpunk46r4AExIRc\nMxkKgUhNlrrv1B21hOaXN/5miE+LOTbrcmU/M9yvC6MVY730GNFoL8IhJ8j8vrOL\npMY22OP6baS1k9YMrtDTlwJHoGby04ThTUeBDksS9RiuHvicZqBedQdIF65pZuhp\neDcGBcLiYasQr/EO5gxxtLyTmgsHSOVSBcFOn9lgv7LECPq9i7mfH3mpxgrRKSxH\npOoZ0KXMcB+hHuvlklHntvcI0mMMQ0mhYj6qtMFStkF1RpCG3IPdIwpVCQqu8GV7\ns8ubknRzs+3C/Bm19RFOoiPpDkwvyNfvmQ14XkyqqKK5oZ8zhD32kFRQkxa8uZSu\nh4aTImFxknu39waBxIRXE4jKxlAmQc4QjFZoq1KmQqQg0J/1JF8RlFvJas1VcjLv\nYlvUB2t6npO6oQjB3l+PNf0DpQH7iUx3Wz5AjQCi6L25FjyE06q6BZ/QlmtYdl/8\nZYao4SRqPEs/6cAiF+Qf5zg2UkaWtDphl1LKMuTNLotvsX99HP69V2faNyegodQ0\nLyTApr/vT01YPE46vNsDLgK+4cL6TrzC/a4WcmF5SRJ938zrv/duJHLXQIku5v0+\nEwOy59Hdm0PT/Er/84dDV0CSjdR/2XuZM3kpysSKLgD1cKiDA+IRguODCxfO9cyY\nIg46v9mFmBvyH04=\n-----END CERTIFICATE-----\n', '-----BEGIN EC PRIVATE KEY-----\nMHcCAQEEIJC0IxOeGTG82VRsrvr5zTRZpGI6Ssp27o+A6FMKG6broAoGCCqGSM49\nAwEHoUQDQgAEIBNjbUBjJiNobBJRaKGB23b5uc83OcstolcZlEWXymqCP3EjgMWX\nHzaMF9T317WVb/uByKzFdIKvcK/67gEvyQ==\n-----END EC PRIVATE KEY-----\n', 0, '', '', '2025-09-17 23:01:58', '2025-07-13 20:37:11');
COMMIT;

-- ----------------------------
-- Table structure for waf_logs
-- ----------------------------
DROP TABLE IF EXISTS `waf_logs`;
CREATE TABLE `waf_logs` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT 1,
  `rule_id` bigint(20) NOT NULL,
  `ip` varchar(64) NOT NULL,
  `host` varchar(64) NOT NULL,
  `url` text NOT NULL,
  `exploit` longtext DEFAULT NULL,
  `request` longtext DEFAULT NULL,
  `country` varchar(64) NOT NULL,
  `province` varchar(64) NOT NULL,
  `city` varchar(64) NOT NULL,
  `latitude` decimal(18,14) NOT NULL,
  `longitude` decimal(18,14) NOT NULL,
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_type` (`rule_id`),
  KEY `idx_ip` (`ip`),
  KEY `idx_host` (`host`),
  KEY `idx_time` (`updated_at`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT;

-- ----------------------------
-- Table structure for waf_ml
-- ----------------------------
DROP TABLE IF EXISTS `waf_ml`;
CREATE TABLE `waf_ml` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT 1,
  `enabled` tinyint(1) NOT NULL DEFAULT 1,
  `host` varchar(64) NOT NULL,
  `uri` text NOT NULL,
  `schema` longtext NOT NULL,
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT;

-- ----------------------------
-- Records of waf_ml
-- ----------------------------
BEGIN;
COMMIT;

-- ----------------------------
-- Table structure for waf_plugins
-- ----------------------------
DROP TABLE IF EXISTS `waf_plugins`;
CREATE TABLE `waf_plugins` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT 1,
  `name` varchar(64) NOT NULL,
  `enabled` tinyint(1) NOT NULL DEFAULT 1,
  `description` text NOT NULL,
  `content` text NOT NULL,
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT;

-- ----------------------------
-- Records of waf_plugins
-- ----------------------------
BEGIN;
INSERT INTO `waf_plugins` (`id`, `uid`, `name`, `enabled`, `description`, `content`, `updated_at`) VALUES (1, 1, 'ip_intelligence', 1, 'IP威胁情报插件，通过IP信誉来判断是否拦截请求', '---\n--- Generated by UUSEC(https://www.uusec.com/)\n--- Created by Safe3.\n--- DateTime: 2024/7/25 11:11\n---\n\nlocal ngx = ngx\nlocal ngx_exit = ngx.exit\nlocal ngx_log = ngx.log\nlocal ngx_err = ngx.ERR\nlocal ngx_today = ngx.today\nlocal ngx_kv = ngx.shared\nlocal http = require(\"resty.http\")\nlocal ipmatcher = require(\"resty.ipmatcher\")\nlocal resty_lock = require(\"resty.lock\")\nlocal util = require(\"waf.util\")\n\nlocal _M = {\n    version = 0.2,\n    name = \"ip-intelligence\"\n}\n\nlocal matcher, last_update_day = nil, \"\"\n\nlocal function init_matcher()\n    local http_client = http.new()\n    http_client:set_timeouts(5000, 10000, 30000)\n\n    local res, err = http_client:request_uri(\"https://download.uusec.com/ip-intelligence-feed.json\")\n    if not res then\n        ngx_log(ngx_err, \"get ip intelligence failed: \", err)\n        return\n    end\n\n    if res.status ~= 200 then\n        return\n    end\n    \n    res, err = util.jsonDecode(res.body)\n    if not res then\n        ngx_log(ngx_err, \"decode ip intelligence feed failed: \", err)\n        return\n    end\n    matcher = ipmatcher.new_with_value(res)\nend\n\nfunction _M.req_pre_filter(waf)\n    local lock, ok, err\n    local today = ngx_today()\n\n    if last_update_day ~= today then\n        lock, err = resty_lock:new(\"lock\")\n        if not lock then\n            ngx_log(ngx_err, \"create ip_threat_lock failed: \", err)\n            return\n        end\n\n        ok, err = lock:lock(\"ip_threat_lock\")\n        if not ok then\n            return\n        end\n\n        if last_update_day ~= today then\n            init_matcher()\n            last_update_day = today\n        end\n\n        ok, err = lock:unlock()\n        if not ok then\n            ngx_log(ngx_err, \"unlock ip_threat_lock failed: \", err)\n        end\n    end\n\n    if matcher then\n        local level = matcher:match(waf.ip)\n        if level then\n            waf.msg = \"ip threat level: \" .. level\n            waf.rule_id = 10000\n            waf.deny = true\n            ngx_kv.ipBlock:incr(waf.ip, 1, 0)\n            return ngx_exit(403)\n        end\n    end\nend\n\nreturn _M', '2025-07-13 20:53:28');
INSERT INTO `waf_plugins` (`id`, `uid`, `name`, `enabled`, `description`, `content`, `updated_at`) VALUES (2, 1, 'kafka_logger', 0, '用于将拦截日志写入Kafka，便于外部分析', '---\n--- Generated by UUSEC(https://www.uusec.com/)\n--- Created by Safe3.\n--- DateTime: 2022/9/21 20:37\n---\nlocal producer = require(\"resty.kafka.producer\")\nlocal log = require(\"waf.log\")\n\nlocal _M = {\n    version = 0.1,\n    name = \"kafka-logger\"\n}\n\nlocal function kafkaLog(_, brokerList, info)\n    local kp = producer:new(brokerList, { producer_type = \"async\" })\n    local key = \"key\"\n    local message = log.encodeJson(info)\n    local ok, err = kp:send(\"waf-log\", key, message)\n    if not ok then\n        log.errLog(_M.name, \" send err: \", err)\n    end\nend\n\nfunction _M.log_post_filter(waf)\n    local brokerList = {\n        {\n            host = \"127.0.0.1\",\n            port = 9092,\n\n            sasl_config = {\n                mechanism = \"PLAIN\",\n                user = \"USERNAME\",\n                password = \"PASSWORD\",\n            },\n        }\n    }\n\n    if waf.rule_id then\n        local country, province, city = log.ip2loc(waf.ip)\n        local info = { rule_id = waf.rule_id, ip = waf.ip, host = waf.host, url = waf.reqUri, data = log.utf8(waf.msg), req = log.utf8(log.getReq()), country = country, province = province, city = city, create_at = ngx.localtime() }\n        log.broker(kafkaLog, brokerList, info)\n    end\nend\n\nreturn _M', '2025-07-01 08:29:33');
COMMIT;

-- ----------------------------
-- Table structure for waf_rules
-- ----------------------------
DROP TABLE IF EXISTS `waf_rules`;
CREATE TABLE `waf_rules` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT 1,
  `level` tinyint(4) NOT NULL,
  `name` varchar(64) NOT NULL,
  `phase` tinyint(4) NOT NULL,
  `type` tinyint(4) NOT NULL,
  `description` text NOT NULL,
  `content` text NOT NULL,
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=500 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT;

-- ----------------------------
-- Records of waf_rules
-- ----------------------------
BEGIN;
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (9, 1, 3, '自定义', 0, 1, '留下备用，用于自定义最高优先级规则', 'return false', '2022-09-01 17:44:13');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (10, 1, 3, 'Invalid protocol', 0, 1, 'querystring参数过多', 'if waf.queryString==nil then\n     return true,waf.qErr,true\nend\nreturn false', '2022-09-01 17:44:13');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (11, 1, 4, 'Invalid protocol', 0, 1, '非法post协议', 'if waf.fErr then\n    if waf.fErr == \"unknown\" then\n        return false\n    end\n    return true, waf.fErr, true\nend\nreturn false', '2024-01-25 23:03:37');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (12, 1, 4, 'Invalid protocol', 0, 1, 'cookie参数过多', 'if waf.cookies==nil then\n     return true,waf.cErr,true\nend\nreturn false', '2022-09-01 17:44:03');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (13, 1, 4, '高频攻击防护', 0, 1, '累计攻击超过10次，则在10分钟内拦截该ip访问', 'local ib = waf.ipBlock\nlocal c = ib:get(waf.ip)\nif c and c >= 10 then\n    ib:set(waf.ip, c, 600, 1)\n    return true, \"ip blocked for continue attack: \" .. waf.ip, true\nend\nreturn false', '2024-05-28 10:44:21');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (14, 1, 3, '代理头sql注入', 0, 1, '过滤http请求中X-Forwarded-For、Client-IP请求头中单引号sql注入', 'local rip=waf.reqHeaders.x_forwarded_for\nif rip then\n	if type(rip) ~= \"string\" then\n		return true,\"Malform X-Forwarded-For\",true\n	elseif waf.contains(rip,\"\'\") then\n		return true,rip,true\n	end\nend\nrip=waf.reqHeaders.client_ip\nif rip then\n	if type(rip) ~= \"string\" then\n		return true,\"Malform Client-IP\",true\n	elseif waf.contains(rip,\"\'\") then\n		return true,rip,true\n	end\nend\nreturn false', '2022-08-22 16:28:33');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (15, 1, 4, '上传文件名过滤', 0, 1, '过滤上传文件名中的网页脚本扩展名，拦截webshell上传', 'local function fileNameMatch(v)\n    v = waf.htmlEntityDecode(v)\n    if v then\n        local m =  waf.rgxMatch(v, \"\\\\.(?:as|cer\\\\b|cdx|ph|jsp|war|class|exe|ht|env|user\\\\.ini)|php\\\\.ini\", \"joi\")\n        if m then\n            return m, v\n        end\n    end\n    return false\nend\nif waf.form then\n    local m, d = waf.knFilter(waf.form[\"FILES\"], fileNameMatch, 1)\n    return m, d, true\nend\n\nreturn false', '2024-09-29 08:14:54');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (16, 1, 4, '上传文件内容过滤', 0, 1, '过滤上传的文件内容，拦截webshell上传', 'local rgx = waf.rgxMatch\nlocal function fileContentMatch(v)\n    local m = rgx(v, \"<\\\\?.+?\\\\$(?:GLOBALS|_(?:GET|POST|COOKIE|REQUEST|SERVER|FILES|SESSION|ENV))|<\\\\?php|<jsp:|<%(?i:!|\\\\s*@|.*?\\\\brequest\\\\s*(?:\\\\.|\\\\())\", \"jos\")\n    if m then\n        return m, v\n    end\n    return false\nend\nif waf.form then\n    local m, d = waf.knFilter(waf.form[\"FILES\"], fileContentMatch, 0)\n    return m, d, true\nend\nreturn false', '2022-09-03 10:12:36');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (17, 1, 2, '扫描器检测', 0, 1, '检测常见的各种扫描器，如awvs、sqlmap、nessus、appscan、nmap等，拦截它们有助于减少黑客发现漏洞的风险', 'local m, d = waf.plugins.scannerDetection.check()\nif m then\n    return true, d, true\nend\nreturn false', '2022-08-21 08:37:35');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (18, 1, 4, 'HTTP Request Smuggling', 0, 1, '此规则查找与单词HTTP/\\d或CR/LF字符组合的HTTP/WEBDAV方法名。这将指向试图将第二个请求注入到请求中，从而绕过对主请求执行的测试，如CVE-2019-20372(Nginx<1.17.7 请求走私漏洞)。参考：http://projects.webappsec.org/HTTP-Request-Smuggling', 'local kvFilter = waf.kvFilter\nlocal rgx = waf.rgxMatch\nlocal htmlEntityDecode = waf.htmlEntityDecode\n\nlocal function rMatch(v)\n    local m = rgx(htmlEntityDecode(v), \"(?:get|post|head|options|connect|put|delete|trace|track|patch|propfind|propatch|mkcol|copy|move|lock|unlock)\\\\s+[^\\\\s]+\\\\s+http/\\\\d\", \"josi\")\n    if m then\n        return m, v\n    end\n    return false\nend\n\nlocal form = waf.form\nif form then\n    local m, d = kvFilter(form[\"FORM\"], rMatch)\n    if m then\n        return m, d, true\n    end\n    m, d = rMatch(form[\"RAW\"])\n    if m then\n        return m, d, true\n    end\nend\n\nlocal queryString = waf.queryString\nif queryString then\n    local m, d = kvFilter(queryString, rMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal cookies = waf.cookies\nif cookies then\n    local m, d = kvFilter(cookies, rMatch)\n    if m then\n        return m, d, true\n    end\nend\nreturn false', '2024-08-08 16:37:51');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (19, 1, 1, '请求方法加强', 0, 1, '不常用的http请求方法会出现一些安全漏洞，如：历史上Apache平台TRACE请求方法出现过XSS相关漏洞', 'if not waf.rgxMatch(waf.method, \"^(?:GET|HEAD|POST|PUT|DELETE|OPTIONS|PROPFIND)$\") then\n    return true, waf.method, true\nend ', '2022-08-22 16:33:27');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (20, 1, 4, 'HTTP Response Splitting', 0, 1, '该规则查找回车符（CR）%0d和换行符（LF）%0a字符。如果在响应报头中返回数据，这些字符可能会导致问题，并且可能会被中间代理服务器解释并被视为两个单独的响应。参考：http://projects.webappsec.org/HTTP-Response-Splitting', 'local kvFilter = waf.kvFilter\nlocal rgx = waf.rgxMatch\nlocal htmlEntityDecode = waf.htmlEntityDecode\n\nlocal function rMatch(v)\n    local m = rgx(v, \"[\\\\r\\\\n]\\\\W*?(?:content-(?:type|length)|set-cookie|location):\\\\s*\\\\w\", \"josi\")\n    if m then\n        return m, v\n    end\n    return false\nend\n\nlocal form = waf.form\nif form then\n    local m, d = kvFilter(form[\"FORM\"], rMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal queryString = waf.queryString\nif queryString then\n    local m, d = kvFilter(queryString, rMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal cookies = waf.cookies\nif cookies then\n    local m, d = kvFilter(cookies, rMatch)\n    if m then\n        return m, d, true\n    end\nend\nreturn false', '2024-01-25 15:04:57');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (21, 1, 4, 'ASP畸形编码过滤', 0, 1, 'asp中unicode畸形编码会造成waf绕过危害', 'if waf.rgxMatch(waf.reqUri,\"%u00(?:aa|ba|d0|de|e2|f0|fe)\",\"i\") then\n return true,waf.reqUri,true\nend\nreturn false', '2022-08-22 16:34:12');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (22, 1, 4, 'Boundary异常拦截', 0, 1, '拦截请求content type头中multipart/form-data的异常boundary，如php在上传解析boundary时没有符合rfc规范，对逗号产生了错误解析。', 'local ct = waf.reqContentType\n\nif ct then\n    if type(ct) ~= \"string\" then\n        return true, \"Malform Content-Type\", true\n    elseif waf.contains(ct, \"boundary\") and (waf.strCounter(ct, \"boundary\") > 1 or not waf.rgxMatch(ct, \"boundary=[0-9A-Za-z\\\\-]+$\", \"jo\")) then\n        return true, ct, true\n    end\nend\n\nreturn false', '2022-08-22 16:34:45');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (24, 1, 4, 'HTTP Splitting', 0, 1, '此规则检测请求文件名中的\\n或\\r。参考：https://www.owasp.org/index.php/Testing_for_HTTP_Splitting/Smuggling_(OTG-INPVAL-016)', 'local rgx = waf.rgxMatch\nlocal function fMatch(v)\n    local m = rgx(v, \"[\\\\n\\\\r]\", \"jo\")\n    if m then\n        return m, v\n    end\n    return false\nend\nlocal m, d = fMatch(waf.uri)\nif m then\n    return m, d, true\nend\nreturn false', '2022-08-22 16:36:34');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (25, 1, 4, 'LDAP Injection', 0, 1, '拦截LDAP注入攻击', 'local kvFilter = waf.kvFilter\nlocal rgx = waf.rgxMatch\nlocal htmlEntityDecode = waf.htmlEntityDecode\n\nlocal function rMatch(v)\n    local m = rgx(htmlEntityDecode(v), \"^[^:\\\\(\\\\)\\\\&\\\\|\\\\!\\\\<\\\\>\\\\~]*\\\\)\\\\s*(?:\\\\((?:[^,\\\\(\\\\)\\\\=\\\\&\\\\|\\\\!\\\\<\\\\>\\\\~]+[><~]?=|\\\\s*[&!|]\\\\s*(?:\\\\)|\\\\()?\\\\s*)|\\\\)\\\\s*\\\\(\\\\s*[\\\\&\\\\|\\\\!]\\\\s*|[&!|]\\\\s*\\\\([^\\\\(\\\\)\\\\=\\\\&\\\\|\\\\!\\\\<\\\\>\\\\~]+[><~]?=[^:\\\\(\\\\)\\\\&\\\\|\\\\!\\\\<\\\\>\\\\~]*)\", \"jos\")\n    if m then\n        return m, v\n    end\n    return false\nend\n\nlocal form = waf.form\nif form then\n    local m, d = kvFilter(form[\"FORM\"], rMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal queryString = waf.queryString\nif queryString then\n    local m, d = kvFilter(queryString, rMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal cookies = waf.cookies\nif cookies then\n    local m, d = kvFilter(cookies, rMatch)\n    if m then\n        return m, d, true\n    end\nend\nreturn false', '2022-08-22 16:36:52');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (27, 1, 4, 'Header头漏洞', 0, 1, 'httpoxy漏洞可被用来针对CGI环境设置非法代理，从而窃取服务器敏感数据。在CVE-2017-7269（IIS 6.0 WebDAV远程代码执行漏洞）中if和lock_token http头会造成溢出攻击。', 'if waf.reqHeaders.proxy ~= nil then\n    return true, \"Proxy: \" .. waf.reqHeaders.proxy, true\nend\n\nif waf.reqHeaders.lock_token ~= nil then\n    return true, \"Lock-Token: \" .. waf.reqHeaders.lock_token, true\nend\n\nif waf.reqHeaders[\"If\"] ~= nil then\n    return true, \"If: \" .. waf.reqHeaders[\"If\"], true\nend\n\nreturn false', '2022-09-07 18:36:30');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (28, 1, 4, 'ImageMagick漏洞', 0, 1, 'ImageMagick是一个功能强大的开源图形处理软件，该漏洞可以执行任意命令和读写文件', 'local rgx = waf.rgxMatch\nlocal function imgContentMatch(v)\n    local m = rgx(v, \"\\\\bpush\\\\s+graphic-context\\\\b|\\\\<\\\\s*image\\\\b\", \"joi\")\n    if m then\n        return m, v\n    end\n    return false\nend\nif waf.form then\n    local m, d = waf.knFilter(waf.form[\"FILES\"], imgContentMatch, 0)\n    return m, d, true\nend\nreturn false', '2022-08-22 16:38:27');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (29, 1, 4, 'XXE漏洞', 0, 1, 'XML外部实体注入(XML External Entity)漏洞简称XXE漏洞。当允许引用外部实体时，通过构造恶意内容，可导致读取任意文件、执行系统命令、探测内网端口、攻击内网网站等危害。', 'if waf.form and waf.form[\"RAW\"] then\n    local m = waf.rgxMatch(waf.form[\"RAW\"], \"<!(?:DOCTYPE|ENTITY)[^>]+?\\\\bSYSTEM\\\\b\", \"jos\")\n    if m then\n        return m, waf.form[\"RAW\"], true\n    end\nend\nreturn false', '2022-09-20 16:29:52');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (41, 1, 4, 'Invalid protocol', 0, 1, '请求header数过多，超过64个。', 'if waf.hErr and waf.hErr==\"truncated\" then\n     return true,waf.hErr,true\nend\nreturn false', '2022-08-16 13:19:46');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (43, 1, 2, '请求body大小限制', 0, 1, '限制请求body大小为8M以下，黑客会尝试大数据包绕过waf过滤', 'if waf.reqContentLength>8388608 then\n    return true,\"reqBody length is \"..waf.reqContentLength ,true\nend\nreturn false', '2022-08-19 18:14:17');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (44, 1, 3, '异常请求字符编码拦截', 0, 1, '黑客通常会在Content-Type头中使用异常的charset定义字符集编码来绕过waf保护，如IBM037, IBM500, cp875等', 'local rct = waf.reqContentType\nlocal has = waf.contains\nlocal counter = waf.strCounter\nlocal rgx = waf.rgxMatch\nif rct then\n    rct = waf.toLower(rct)\n    if has(rct, \"charset\") and (not rgx(rct, \"charset\\\\s*=\\\\s*(utf\\\\-8|gbk|gb2312|iso\\\\-8859\\\\-1|iso\\\\-8859\\\\-15|windows\\\\-1252)\",\"jo\") or counter(rct, \"charset\") > 1) then\n        return true, rct, true\n    end\nend\nreturn false', '2022-08-22 16:39:49');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (45, 1, 4, '常规sql注入检测', 0, 1, '检测url、cookie、form、header中的sql注入攻击。采用SQL语义检测引擎，可以降低误报。', 'local checkSQLI = waf.checkSQLI\nlocal kvFilter = waf.kvFilter\n\nlocal function match(v)\n    if checkSQLI(v) then\n        return true, v\n    end\n    return false\nend\n\nlocal function sMatch(v)\n    if checkSQLI(v, 3) then\n        return true, v\n    end\n    return false\nend\n\nlocal form = waf.form\nif form then\n    local m, d = kvFilter(form[\"FORM\"], sMatch, true)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal queryString = waf.queryString\nif queryString then\n    local m, d = kvFilter(queryString, sMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal cookies = waf.cookies\nif cookies then\n    local m, d = kvFilter(cookies, sMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal m, d = kvFilter(waf.reqHeaders, match)\nif m then\n    return m, d, true\nend\n\nreturn false', '2024-11-16 17:36:03');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (46, 1, 4, 'JSON sql注入检测', 0, 1, '解析请求body中的json内容，并检测sql注入攻击。采用SQL语义检测引擎，可以降低误报。', 'local function rMatch(v)\n    if waf.checkSQLI(v, 2) then\n        return true, v\n    end\n    return false\nend\n\nlocal form = waf.form\nif form then\n    local m, d = waf.jsonFilter(form[\"RAW\"], rMatch, false)\n    if m then\n        return m, d, true\n    end\nend\n\nreturn false', '2024-01-25 12:23:40');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (47, 1, 4, '常规命令注入检测', 0, 1, '检测url、cookie、form中的shell命令注入攻击，采用RCE语义检测引擎可以检查各种变形，如：cat$IFS/etc/os-release或c$()at /e??/p?????等', 'local checkRCE = waf.checkRCE\nlocal kvFilter = waf.kvFilter\n\nlocal function rMatch(v)\n    if checkRCE(v, 1) then\n        return true, v\n    end\n    return false\nend\n\nlocal function rMatch1(v)\n    if checkRCE(v, 0) then\n        return true, v\n    end\n    return false\nend\n\nlocal function rMatch2(v)\n    if checkRCE(v, 2) then\n        return true, v\n    end\n    return false\nend\n\nlocal form = waf.form\nif form then\n    local m, d = kvFilter(form[\"FORM\"], rMatch, true)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal queryString = waf.queryString\nif queryString then\n    local m, d = kvFilter(queryString, rMatch2)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal cookies = waf.cookies\nif cookies then\n    local m, d = kvFilter(cookies, rMatch1, true)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal m, d = kvFilter(waf.reqHeaders, rMatch)\nif m then\n    return m, d, true\nend\nreturn false', '2024-12-28 15:13:55');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (48, 1, 4, 'JSON 命令注入检测', 0, 1, '解析请求body中的json内容，并检测命令注入攻击。采用RCE语义检测引擎可以检查各种变形，如：cat$IFS/etc/os-release或c$()at /e??/p?????等', 'local function rMatch(v)\n    if waf.checkRCE(v) then\n        return true, v\n    end\n    return false\nend\n\nlocal form = waf.form\nif form then\n    local m, d = waf.jsonFilter(form[\"RAW\"], rMatch, false, true)\n    if m then\n        return m, d, true\n    end\nend\n\nreturn false', '2024-01-25 12:21:24');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (49, 1, 3, '路径遍历攻击', 0, 1, '检测url、上传文件或参数中的路径遍历攻击。采用LFI语义检测引擎，可以检查如：/////..\\\\..\\\\etc///passwd等变形攻击。', 'local checkPT = waf.checkPT\nlocal kvFilter = waf.kvFilter\n\nlocal function ptMatch(v)\n    local m = checkPT(v)\n    if m then\n        return m, v\n    end\n    return false\nend\n\nlocal function ptMatch1(v)\n    local m = checkPT(v)\n    if m then\n        return m, v\n    end\n    m = checkPT(waf.base64Decode(v))\n    if m then\n        return m, v\n    end\n    return false\nend\n\nif checkPT(waf.uri) then\n    return true, waf.uri, true\nend\n\nlocal form = waf.form\nif form then\n    local m, d = kvFilter(form[\"FORM\"], ptMatch)\n    if m then\n        return m, d, true\n    end\n    m, d = waf.knFilter(waf.form[\"FILES\"], ptMatch, 1)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal queryString = waf.queryString\nif queryString then\n    local m, d = kvFilter(queryString, ptMatch1)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal m, d = kvFilter(waf.reqHeaders, ptMatch)\nif m then\n    return m, d, true\nend\n\nreturn false', '2024-12-28 17:39:22');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (50, 1, 2, '敏感文件泄露检测', 0, 1, '检测url中各种敏感泄露文件的路径，如svn、git、sql、log、bak等，防止被攻击者利用', 'local m, d = waf.plugins.fileLeakDetection.check()\nif m then\n    return true, d, true\nend\nreturn false', '2022-08-22 16:43:49');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (51, 1, 4, '远程文件包含 (RFI)', 0, 1, '该规则寻找常见类型的远程文件包含（RFI）攻击方法。\n#-PHP“include（）”函数\n#-JSP <jsp:include page= 或 <c:import url=\n#-RFI主机与本地主机不匹配', 'local kvFilter = waf.kvFilter\nlocal rgx = waf.rgxMatch\nlocal host = waf.host\nlocal counter = waf.strCounter\nlocal str_find = string.find\nlocal str_sub = string.sub\n\nlocal function rMatch(v)\n    local m = rgx(v, \"^\\\\s*(?:(?:url|jar):)?(file|ftps?|gopher|ldap)://\", \"joi\")\n    if m then\n        local i, j = str_find(v, waf.getRootDomain(host), 1, true)\n        if i then\n            if counter(str_sub(v, 1, j), \"/\") == 2 then\n                return false\n            end\n        end\n    end\n    return m, v\nend\n\nlocal form = waf.form\nif form then\n    local m, d = kvFilter(form[\"FORM\"], rMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal queryString = waf.queryString\nif queryString then\n    local m, d = kvFilter(queryString, rMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nreturn false', '2024-12-28 21:48:03');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (52, 1, 4, 'Shellshock漏洞', 0, 1, '检测对“Shellshock”(CVE-2014-6271和CVE-2014-7169) GNU Bash RCE漏洞的攻击。', 'local kvFilter = waf.kvFilter\nlocal rgx = waf.rgxMatch\nlocal requestLine = waf.requestLine\nlocal urlDecode = waf.urlDecode\n\nlocal function rMatch(v)\n    local m = rgx(urlDecode(v), \"\\\\(\\\\s*\\\\)\\\\s+{\", \"jos\")\n    if m then\n        return m, v\n    end\n    return false\nend\n\nlocal m, d = kvFilter(waf.reqHeaders, rMatch)\nif m then\n    return m, d, true\nend\n\nlocal m, d = rMatch(requestLine)\nif m then\n    return m, d, true\nend\n\nreturn false', '2022-08-22 16:44:48');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (53, 1, 3, 'php安全规则集', 0, 1, '检测php相关的对象序列化等漏洞', 'local kvFilter = waf.kvFilter\nlocal rgx = waf.rgxMatch\n\nlocal function sMatch(v)\n    local m = rgx(v, \"php://(?:std(?:in|out|err)|(?:in|out)put|fd|memory|temp|filter)|(?:ssh2(?:.(?:s(?:(?:ft|c)p|hell)|tunnel|exec))?|z(?:lib|ip)|(?:ph|r)ar|expect|bzip2|glob|ogg)://|\\\\bphpinfo\\\\s*\\\\(\\\\s*\\\\)\", \"joi\")\n    if m then\n        return m, v\n    end\n    m = rgx(v, \"[oOcC]:\\\\d+:\\\"\\\\w+\\\":\\\\d+:{.*?}\", \"jos\")\n    if m then\n        return m, v\n    end\n    return false\nend\n\nlocal function fileContentMatch(v)\n    local m = rgx(v, \"<\\\\?.+?\\\\$_(?:GET|POST|COOKIE|REQUEST|SERVER|FILES|SESSION)|<\\\\?php\", \"jos\")\n    if m then\n        return m, v\n    end\n    return false\nend\n\nif rgx(waf.uri, \"\\\\.php\\\\.\", \"joi\") then\n    return true, waf.uri, true\nend\n\nlocal form = waf.form\nif form then\n    local m, d = kvFilter(form[\"FORM\"], sMatch)\n    if m then\n        return m, d, true\n    end\n    m, d = waf.knFilter(form[\"FILES\"], fileContentMatch, 0)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal queryString = waf.queryString\nif queryString then\n    local m, d = kvFilter(queryString, sMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal cookies = waf.cookies\nif cookies then\n    local m, d = kvFilter(cookies, sMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal m, d = kvFilter(waf.reqHeaders, sMatch)\nif m then\n    return m, d, true\nend\nreturn false', '2024-12-28 15:21:33');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (54, 1, 3, '通用攻击', 0, 1, '本规则拦截ruby、node、js、perl注入和SSRF攻击', 'local kvFilter = waf.kvFilter\nlocal rgx = waf.rgxMatch\n\nlocal function sMatch(v)\n    local m = rgx(v, \"Process\\\\s*\\\\.\\\\s*spawn\\\\s*\\\\(\", \"jos\")\n    if m then\n        return m, \"Ruby Injection Attack: \"..v\n    end\n    m = rgx(v, \"t(?:his\\\\.constructor|runcateSync\\\\s*\\\\()|\\\\b(?:spawn|eval)\\\\s*\\\\(|_(?:\\\\$\\\\$ND_FUNC\\\\$\\\\$_|_js_function)|String\\\\s*\\\\.\\\\s*fromCharCode\", \"jos\")\n    if m then\n        return m, \"Node.js Injection Attack: \"..v\n    end\n    m = rgx(v, \"__proto__|constructor\\\\s*(?:\\\\.|\\\\[)\\\\s*prototype\", \"jos\")\n    if m then\n        return m, \"JavaScript Prototype Pollution: \"..v\n    end\n    m = rgx(v, \"(?:s(?:sh(?:2(?:.(?:s(?:(?:ft|c)p|hell)|tunnel|exec))?)?|m(?:[bs]|tps?)|vn(?:\\\\+ssh)?|n(?:ews|mp)|ips?|ftp|3)|p(?:op(?:3s?|2)|r(?:oxy|es)|h(?:ar|p)|aparazzi|syc)|c(?:ompress.(?:bzip2|zlib)|a(?:llto|p)|id|vs)|t(?:e(?:amspeak|lnet)|urns?|ftp)|f(?:i(?:nger|sh)|(?:ee)?d|tps?)|i(?:rc[6s]?|maps?|pps?|cap|ax)|d(?:a(?:ta|v)|n(?:tp|s)|ict)|m(?:a(?:ilto|ven)|umble|ms)|n(?:e(?:tdoc|ws)|ntps?|fs)|r(?:tm(?:f?p)?|sync|ar|mi)|v(?:iew-source|entrilo|nc)|a(?:ttachment|f[ps]|cap)|b(?:eshare|itcoin|lob)|g(?:o(?:pher)?|lob|it)|u(?:nreal|t2004|dp)|e(?:xpect|d2k)|h(?:ttps?|323)|w(?:ebcal|s?s)|ja(?:bbe)?r|x(?:mpp|ri)|ldap[is]?|ogg|zip):\\\\/\\\\/(?:(?:[\\\\d.]{0,11}(?:(?:\\\\xe2(?:\\\\x92(?:[\\\\x9c\\\\x9d\\\\x9e\\\\x9f\\\\xa0\\\\xa1\\\\xa2\\\\xa3\\\\xa4\\\\xa5\\\\xa6\\\\xa7\\\\xa8\\\\xa9\\\\xaa\\\\xab\\\\xac\\\\xad\\\\xae\\\\xaf\\\\xb0\\\\xb1\\\\xb2\\\\xb3\\\\xb4\\\\xb5]|[\\\\x88\\\\x89\\\\x8a\\\\x8b\\\\x8c\\\\x8d\\\\x8e\\\\x8f\\\\x90\\\\x91\\\\x92\\\\x93\\\\x94\\\\x95\\\\x96\\\\x97\\\\x98\\\\x99\\\\x9a\\\\x9b]|[\\\\xb6\\\\xb7\\\\xb8\\\\xb9\\\\xba\\\\xbb\\\\xbc\\\\xbd\\\\xbe\\\\xbf]|[\\\\x80\\\\x81\\\\x82\\\\x83\\\\x84\\\\x85\\\\x86\\\\x87])|\\\\x93(?:[\\\\x80\\\\x81\\\\x82\\\\x83\\\\x84\\\\x85\\\\x86\\\\x87\\\\x88\\\\x89\\\\x8a\\\\x8b\\\\x8c\\\\x8d\\\\x8e\\\\x8f]|[\\\\x9c\\\\x9d\\\\x9e\\\\x9f\\\\xa0\\\\xa1\\\\xa2\\\\xa3\\\\xa4\\\\xa5\\\\xa6\\\\xa7\\\\xa8\\\\xa9]|[\\\\x90\\\\x91\\\\x92\\\\x93\\\\x94\\\\x95\\\\x96\\\\x97\\\\x98\\\\x99\\\\x9a\\\\x9b]|[\\\\xbf\\\\xb5\\\\xb6\\\\xb7\\\\xb8\\\\xb9\\\\xba\\\\xbb\\\\xbc\\\\xbd\\\\xbe]|[\\\\xab\\\\xac\\\\xad\\\\xae\\\\xaf\\\\xb0\\\\xb1\\\\xb2\\\\xb3\\\\xb4])|\\\\x91(?:[\\\\xaa\\\\xa0\\\\xa1\\\\xa2\\\\xa3\\\\xa4\\\\xa5\\\\xa6\\\\xa7\\\\xa8\\\\xa9\\\\xaa\\\\xab\\\\xac\\\\xad\\\\xae\\\\xaf\\\\xb0\\\\xb1\\\\xb2\\\\xb3]|[\\\\xb4\\\\xb5\\\\xb6\\\\xb7\\\\xb8\\\\xb9\\\\xba\\\\xbb\\\\xbc\\\\xbd\\\\xbe\\\\xbf]))|\\\\xe3\\\\x80\\\\x82))+)|[a-z][\\\\w\\\\-\\\\.]{1,255}:\\\\d{1,5}(?:#?\\\\s*&?@(?:(?:\\\\d{1,3}\\\\.){3,3}\\\\d{1,3}|[a-z][\\\\w\\\\-\\\\.]{1,255}):\\\\d{1,5}\\\\/?)+|(?:0x[a-f0-9]{2}\\\\.){3}0x[a-f0-9]{2}|(?:0{1,4}\\\\d{1,3}\\\\.){3}0{1,4}\\\\d{1,3}|\\\\d{1,3}\\\\.(?:\\\\d{1,3}\\\\.\\\\d{5}|\\\\d{8})|0x(?:[a-f0-9]{16}|[a-f0-9]{8})|\\\\[[a-f\\\\d:]+(?:[\\\\d.]+|%\\\\w+)?\\\\]|(?:\\\\x5c\\\\x5c[a-z\\\\d-]\\\\.?_?)+|\\\\d{10})\", \"josi\")\n    if m then\n        return m, \"Possible Server Side Request Forgery (SSRF) Attack: \"..v\n    end\n    m = rgx(v, \"\\\\@\\\\{.*?\\\\}\", \"jos\")\n    if m then\n        return m, \"Perl Injection Attack: \"..v\n    end\n    return false\nend\n\nlocal form = waf.form\nif form then\n    local m, d = kvFilter(form[\"FORM\"], sMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal queryString = waf.queryString\nif queryString then\n    local m, d = kvFilter(queryString, sMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal cookies = waf.cookies\nif cookies then\n    local m, d = kvFilter(cookies, sMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal m, d = kvFilter(waf.reqHeaders, sMatch)\nif m then\n    return m, d, true\nend\nreturn false\n', '2022-09-09 13:41:33');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (55, 1, 4, 'Java安全规则集', 0, 1, '检测spring、struts、java序列化等相关安全漏洞', 'local kvFilter = waf.kvFilter\nlocal rgx = waf.rgxMatch\nlocal check = waf.plugins.javaClassDetection.check\n\nlocal function sMatch(v)\n    local m = rgx(v, \"(?:\\\\$\\\\{)+(?:j(?:n|\\\\$\\\\{)|\\\\$\\\\{(?:\\\\w*:)+)\", \"joi\")\n    if m then\n        return m, \"Potential Log4j / Log4shell Attack: \" .. v\n    end\n    m = rgx(v, \"^\\\\xac\\\\xed\\\\x00\\\\x05|\\\\b(?:aced0005|rO0AB[XQ]|KztAAU|Cs7QAF)\", \"jo\")\n    if m then\n        return m, \"Magic bytes Detected, probable java serialization Attack: \" .. v\n    end\n    m = rgx(v, \"[#\\\\.]\\\\s*context\\\\s*\\\\.\\\\s*[a-zA-Z]{3,}\", \"jos\")\n    if m then\n        return m, \"Spring Framework RCE: \" .. v\n    end\n    m = check(v)\n    if m then\n        return m, \"Potential dangerous java class: \" .. v\n    end\n    return false\nend\n\nlocal function sMatch1(v)\n    local m = rgx(v, \"^\\\\s*\\\\{\\\\{.+\\\\}\\\\}\\\\s*$\", \"jos\")\n    if m then\n        return m, \"SSTI: \" .. v\n    end\n    v = waf.base64Decode(v)\n    if not v then\n        return false\n    end\n    m = rgx(v, \"^\\\\s*\\\\{\\\\{.+\\\\}\\\\}\\\\s*$\", \"jos\")\n    if m then\n        return m, \"SSTI: \" .. v\n    end\n    m = rgx(v, \"[#\\\\.]\\\\s*context\\\\s*\\\\.\\\\s*[a-zA-Z]{3,}\", \"jos\")\n    if m then\n        return m, \"Spring Framework RCE: \" .. v\n    end\n    m = check(v)\n    if m then\n        return m, \"Potential dangerous java class: \" .. v\n    end\n    return false\nend\n\nif sMatch(waf.urlDecode(waf.reqUri)) then\n    return true, waf.reqUri, true\nend\n\nlocal form = waf.form\nif form then\n    local m, d = kvFilter(form[\"FORM\"], sMatch)\n    if m then\n        return m, d, true\n    end\n    local raw = form[\"RAW\"]\n    m = rgx(raw, \"^\\\\xac\\\\xed\\\\x00\\\\x05|\\\\b(?:aced0005|rO0AB[XQ]|KztAAU|Cs7QAF)\", \"jo\")\n    if m then\n        return m, raw, true\n    end\n    m = check(raw)\n    if m then\n        return m, raw, true\n    end\nend\n\nlocal queryString = waf.queryString\nif queryString then\n    local m, d = kvFilter(queryString, sMatch)\n    if m then\n        return m, d, true\n    end\n    m, d = kvFilter(queryString, sMatch1)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal cookies = waf.cookies\nif cookies then\n    local m, d = kvFilter(cookies, sMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal m, d = kvFilter(waf.reqHeaders, sMatch)\nif m then\n    return m, d, true\nend\n\nreturn false', '2024-12-29 15:13:17');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (56, 1, 4, 'XSS跨站脚本攻击', 0, 1, '攻击者通常会在有漏洞的程序中插入 JavaScript、VBScript、 ActiveX或Flash以欺骗用户。一旦得手，他们可以盗取用户帐户，修改用户设置，盗取/污染cookie，做虚假广告等。', 'local kvFilter = waf.kvFilter\nlocal checkXSS = waf.checkXSS\n\nlocal function sMatch(v)\n    local m = checkXSS(v) or waf.rgxMatch(v,\"\\\\b(?:parent|frames|window|this|self|globalThis|top)\\\\s*(?:/\\\\*|\\\\[\\\\s*[\'/\\\"\\\\(])|\\\\.\\\\s*(?:constructor|getPrototypeOf)\\\\s*\\\\(\",\"jos\")\n    if m then\n        return m, v\n    end\n    return false\nend\n\nlocal form = waf.form\nif form then\n    local m, d = kvFilter(form[\"FORM\"], sMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal queryString = waf.queryString\nif queryString then\n    local m, d = kvFilter(queryString, sMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal cookies = waf.cookies\nif cookies then\n    local m, d = kvFilter(cookies, sMatch)\n    if m then\n        return m, d, true\n    end\nend\n\nlocal m, d = sMatch(waf.userAgent)\nif m then\n    return m, d, true\nend\n\nm, d = sMatch(waf.urlDecode(waf.referer))\nif m then\n    return m, d, true\nend\n\nreturn false', '2024-12-28 16:58:46');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (58, 1, 3, '数据泄露检测', 2, 1, '从返回页面检测列目录漏洞和源代码泄露问题', 'local rgx = waf.rgxMatch\nlocal rb = waf.respBody\n\nlocal m = rgx(rb, \"<(?:TITLE>Index of.*?<H|title>Index of.*?<h)1>Index of|>\\\\[To Parent Directory\\\\]</[Aa]><br>\", \"jo\")\nif m then\n    return m, \"Directory Listing: \" .. rb, true\nend\n\nm = rgx(rb, \"^\\\\s*(?:#\\\\!\\\\s?/|<%|<\\\\?\\\\s*[^x]|<jsp:)\", \"jo\")\nif m then\n    return m, \"Source code leak: \" .. rb, true\nend\n\nreturn false', '2022-08-23 11:31:33');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (59, 1, 1, 'Java报错检测', 2, 1, '返回页面的java报错可能会泄露服务器敏感信息', 'local check = waf.plugins.javaErrorDetection.check\nlocal rb = waf.respBody\n\nif waf.status == 500 then\n    local m,d = check(rb)\n    if m then\n        return m, \"Java error: \" .. d, true\n    end\nend\n\nreturn false', '2022-08-23 11:31:49');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (60, 1, 3, 'SQL报错检测', 2, 1, '返回页面的sql报错可能会泄露服务器敏感信息', 'local check = waf.plugins.sqlErrorDetection.check\nlocal rb = waf.respBody\nlocal rgx = waf.rgxMatch\nlocal has = waf.contains\n\nif waf.status == 500 then\n    local m = check(rb)\n    if m then\n        if rgx(rb, \"JET Database Engine|Access Database Engine|\\\\[Microsoft\\\\]\\\\[ODBC Microsoft Access Driver\\\\]\", \"jo\") then\n            return m, \"Microsoft Access SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"ORA-[0-9][0-9][0-9][0-9]|java\\\\.sql\\\\.SQLException|Oracle error|Oracle.*Driver|Warning.*oci_.*|Warning.*ora_.*\", \"jo\") then\n            return m, \"Oracle SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"DB2 SQL error:|\\\\[IBM\\\\]\\\\[CLI Driver\\\\]\\\\[DB2/6000\\\\]|CLI Driver.*DB2|DB2 SQL error|db2_\\\\w+\\\\(\", \"jo\") then\n            return m, \"DB2 SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"\\\\[DM_QUERY_E_SYNTAX\\\\]|has occurred in the vicinity of:\", \"jo\") then\n            return m, \"EMC SQL Information Leakage: \" .. rb, true\n        end\n        if has(rb, \"Dynamic SQL Error\") then\n            return m, \"firebird SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"Exception (?:condition )?\\\\d+\\\\. Transaction rollback\\\\.\", \"jo\") then\n            return m, \"Frontbase SQL Information Leakage: \" .. rb, true\n        end\n        if has(rb, \"org.hsqldb.jdbc\") then\n            return m, \"hsqldb SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"An illegal character has been found in the statement|com\\\\.informix\\\\.jdbc|Exception.*Informix\", \"jo\") then\n            return m, \"informix SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"Warning.*ingres_|Ingres SQLSTATE|Ingres\\\\W.*Driver\", \"jo\") then\n            return m, \"ingres SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"<b>Warning</b>: ibase_|Unexpected end of command in statement\", \"jo\") then\n            return m, \"interbase SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"SQL error.*POS[0-9]+|Warning.*maxdb\", \"jo\") then\n            return m, \"maxDB SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"System\\\\.Data\\\\.OleDb\\\\.OleDbException|\\\\[Microsoft\\\\]\\\\[ODBC SQL Server Driver\\\\]|\\\\[Macromedia\\\\]\\\\[SQLServer JDBC Driver\\\\]|\\\\[SqlException|System\\\\.Data\\\\.SqlClient\\\\.SqlException|Unclosed quotation mark after the character string|\'80040e14\'|mssql_query\\\\(\\\\)|Microsoft OLE DB Provider for ODBC Drivers|Microsoft OLE DB Provider for SQL Server|Incorrect syntax near|Sintaxis incorrecta cerca de|Syntax error in string in query expression|Procedure or function .* expects parameter|Unclosed quotation mark before the character string|Syntax error .* in query expression|Data type mismatch in criteria expression\\\\.|ADODB\\\\.Field \\\\(0x800A0BCD\\\\)|the used select statements have different number of columns|OLE DB.*SQL Server|Warning.*mssql_.*|Driver.*SQL[ _-]*Server|SQL Server.*Driver|SQL Server.*[0-9a-fA-F]{8}|Exception.*\\\\WSystem\\\\.Data\\\\.SqlClient\\\\.\", \"jo\") then\n            return m, \"Mssql SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"MyS(?:QL server version for the right syntax to use|qlClient\\\\.)|(?:supplied argument is not a valid |SQL syntax.*)MySQL|Column count doesn\'t match(?: value count at row)?|(?:Table \'[^\']+\' doesn\'t exis|valid MySQL resul)t|You have an error in your SQL syntax(?: near|;)|Warning.{1,10}mysql_(?:[a-z_()]{1,26})?|ERROR [0-9]{4} \\\\([a-z0-9]{5}\\\\):|mysql_fetch_array\\\\(\\\\)|on MySQL result index|\\\\[MySQL\\\\]\\\\[ODBC\", \"jo\") then\n            return m, \"Mysql SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"PostgreSQL query failed:|pg_query\\\\(\\\\) \\\\[:|pg_exec\\\\(\\\\) \\\\[:|PostgreSQL.{1,20}ERROR|Warning.*\\\\bpg_.*|valid PostgreSQL result|Npgsql\\\\.|PG::[a-zA-Z]*Error|Supplied argument is not a valid PostgreSQL .*? resource|Unable to connect to PostgreSQL server\", \"jo\") then\n            return m, \"Postgres SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"Warning.*sqlite_|Warning.*SQLite3::|SQLite/JDBCDriver|SQLite\\\\.Exception|System\\\\.Data\\\\.SQLite\\\\.SQLiteException\", \"jo\") then\n            return m, \"SQLite SQL Information Leakage: \" .. rb, true\n        end\n        if rgx(rb, \"Sybase message:|Warning.{2,20}sybase|Sybase.*Server message\", \"jo\") then\n            return m, \"Sybase SQL Information Leakage: \" .. rb, true\n        end\n    end\nend\n\nreturn false', '2022-08-23 11:31:57');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (61, 1, 1, 'PHP报错检测', 2, 1, '返回页面的php报错可能会泄露服务器敏感信息', 'local check = waf.plugins.phpErrorDetection.check\nlocal rb = waf.respBody\n\nif waf.status == 500 then\n    local m, d = check(rb)\n    if m then\n        return m, \"php error: \" .. d, true\n    end\nend\n\nreturn false', '2022-08-23 11:32:04');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (62, 1, 1, 'IIS报错检测', 2, 1, 'IIS返回页面的报错可能会泄露服务器敏感信息', 'local rgx = waf.rgxMatch\nlocal rb = waf.respBody\n\nlocal m = rgx(rb, \"[a-z]:\\\\x5cinetpub\\\\b\", \"jo\")\nif m then\n    return m, rb, true\nend\n\nif waf.status == 500 then\n    local m = rgx(rb, \"Microsoft OLE DB Provider for SQL Server(?:</font>.{1,20}?error \'800(?:04005|40e31)\'.{1,40}?Timeout expired| \\\\(0x80040e31\\\\)<br>Timeout expired<br>)|<h1>internal server error</h1>.*?<h2>part of the server has crashed or it has a configuration error\\\\.</h2>|cannot connect to the server: timed out\", \"jo\")\n    if m then\n        return m, rb, true\n    end\n    local m = rgx(rb, \"\\\\b(?:A(?:DODB\\\\.Command\\\\b.{0,100}?\\\\b(?:Application uses a value of the wrong type for the current operation\\\\b|error\')| trappable error occurred in an external object\\\\. The script cannot continue running\\\\b)|Microsoft VBScript (?:compilation (?:\\\\(0x8|error)|runtime (?:Error|\\\\(0x8))\\\\b|Object required: \'|error \'800)|<b>Version Information:</b>(?:&nbsp;|\\\\s)(?:Microsoft \\\\.NET Framework|ASP\\\\.NET) Version:|>error \'ASP\\\\b|An Error Has Occurred|>Syntax error in string in query expression|/[Ee]rror[Mm]essage\\\\.aspx?\\\\?[Ee]rror\\\\b\", \"jo\")\n    if m then\n        return m, rb, true\n    end\nend\n\nif waf.status == 404 then\n    local m = rgx(rb, \"\\\\bServer Error in.{0,50}?\\\\bApplication\\\\b\", \"jo\")\n    if m then\n        return m, rb, true\n    end\nend\n\nreturn false', '2022-08-23 11:32:15');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (64, 1, 4, 'FastJSON漏洞拦截', 0, 1, '拦截fastjson漏洞漏洞攻击', 'local jsonFilter = waf.jsonFilter\n\nlocal function rMatch(v)\n    if v == \"@type\" then\n        return true, v\n    end\n    return false\nend\n\nlocal form = waf.form\nif form then\n    local raw = form[\"RAW\"]\n    local m = jsonFilter(raw, rMatch, false)\n    if m then\n        return m, raw, true\n    end\nend\n\nreturn false', '2022-09-01 19:00:52');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (65, 1, 2, '弱口令检测', 0, 1, '检测常见登录页面的弱口令问题', 'local check = waf.plugins.weakPwdDetection.check\nlocal toLower = waf.toLower\nlocal has = waf.contains\n\nlocal form = waf.form\nlocal uri = toLower(waf.uri)\nif form and (has(uri, \"login\") or has(uri, \"logon\") or has(uri, \"signin\")) then\n    local f = form[\"FORM\"]\n    if f then\n        for k, v in pairs(f) do\n            k = toLower(k)\n            if (k == \"pass\" or has(k, \"pwd\") or has(k, \"passwd\") or has(k, \"password\")) and check(v) then\n                return true, form[\"RAW\"], false\n            end\n        end\n    end\nend\n\nreturn false', '2022-11-23 18:30:06');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (66, 1, 2, '防CC攻击规则', 0, 1, '当一分钟访问/api/路径频率超过100次，则在5分钟内拦截该ip访问', 'if not waf.startWith(waf.toLower(waf.uri), \"/api/\") then\n    return false\nend\n\n-- 验证搜索引擎并排除，防止影响收录\nlocal se, ok = waf.searchEngineValid({\"180.76.76.76\"}, waf.ip, waf.userAgent)\nif se and ok then\n    return false\nend\n\nlocal sh = waf.ipCache\nlocal ccIp = \'cc-\' .. waf.ip\nlocal c, f = sh:get(ccIp)\nif not c then\n    sh:set(ccIp, 1, 60, 1)  -- 设置1分钟也就是60秒访问计数时间\nelse\n    if f == 2 then\n        return waf.block(true)     -- 重置TCP连接，不记录日志\n    end\n    sh:incr(ccIp, 1)\n    if c + 1 >= 100 then\n        sh:set(ccIp, c + 1, 300, 2)  -- 设置5分钟也就是300秒拦截时间\n        return true, ccIp, true\n    end\nend\n\nreturn false', '2025-06-30 10:38:56');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (68, 1, 2, '机器人攻击防护', 0, 1, '通过生成滑动旋转验证码来拦截机器人攻击，如漏洞扫描、网络爬虫、CC攻击等自动化攻击行为，Token有效期30分钟。', '-- 验证搜索引擎并排除，防止影响收录\nlocal se, ok = waf.searchEngineValid({\"180.76.76.76\"}, waf.ip, waf.userAgent)\nif se and ok then\n    return false\nend\n\nlocal sh = waf.ipCache\nlocal robotIp = \'rb:\' .. waf.ip\nlocal c, f = sh:get(robotIp)\n\nif not c then\n    sh:set(robotIp, 1, 60, 1)  -- 设置1分钟也就是60秒访问计数时间段\nelse\n    if f == 2 then\n        return waf.checkRobot(waf)     -- 启动机器人滑动旋转验证码验证\n    end\n    sh:incr(robotIp, 1)\n    if c + 1 >= 360 then\n        sh:set(robotIp, c + 1, 1800, 2)  -- 达到了60秒内请求超过360次的阈值，进入机器人验证模式\n        return true, robotIp, true\n    end\nend\n\nreturn false', '2025-06-30 10:33:19');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (69, 1, 1, '区域访问限制', 0, 1, '限制非大陆地区访问', '-- 验证搜索引擎并排除，防止影响收录\nlocal se, ok = waf.searchEngineValid({\"180.76.76.76\"}, waf.ip, waf.userAgent)\nif se and ok then\n    return false\nend\n\nlocal _, _, _, iso_code = waf.ip2loc(waf.ip)\nif iso_code ~= \"CN\" and iso_code ~= \"\" then\n    return true, \"限制非大陆地区访问\", true\nend\nreturn false', '2025-06-30 10:42:01');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (70, 1, 1, '高频错误防护', 1, 1, '404出现次数过多，通常为扫描或cc攻击。一分钟内出现超过10次404请求就拦截该ip访问。', 'local sh = waf.ipCache\nlocal ccIp = \'404-\' .. waf.ip\nlocal c, f = sh:get(ccIp)\nif f == 2 then\n    return waf.block(true)     -- 重置TCP连接，不记录日志\nend\nif waf.status ~= 404 then\n    return false\nend\nif not c then\n        sh:set(ccIp, 1, 60, 1)  -- 设置1分钟也就是60秒访问计数时间\nelse\n    sh:incr(ccIp, 1)\n    if c + 1 >= 10 then\n        sh:set(ccIp, c + 1, 300, 2)  -- 设置5分钟也就是300秒拦截时间\n        return true, ccIp, true\n    end\nend\nreturn false', '2024-08-08 16:31:50');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (71, 1, 1, 'Turnstile人机验证', 0, 1, '使用Cloudflare Turnstile来进行自动人机验证，可拦截CC攻击和机器人爬虫等。客户端ip地址认证成功后时间达到600秒或请求次数达到18000次后再次显示验证页面。 请先去Cloudflare注册免费Turnstile组件，获取对应的sitekey和secret，然后填入下列规则中使规则生效。', 'local sitekey = \"\"\nlocal secret = \"\"\nif sitekey ~= \"\" and secret ~= \"\" then\n    -- 验证搜索引擎并排除，防止影响收录\n    local se, ok = waf.searchEngineValid({\"180.76.76.76\"}, waf.ip, waf.userAgent)\n    if se and ok then\n        return false\n    end\n    return waf.checkTurnstile(waf, sitekey, secret, 600, 18000)\nend', '2025-06-30 10:32:27');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (72, 1, 2, '异常Cookie', 0, 1, '拦截老旧的Cookie版本支持功能$Version和双引号值，以防止WAF被绕过进而攻击网站', 'local headers = waf.reqHeaders\n\nif headers then\n    local cookies = headers.cookie\n    if type(cookies) == \"table\" then\n        cookies = table.concat(cookies, \"; \")\n    end\n    if cookies and waf.rgxMatch(cookies, [[\\$Version\\b\\s*=|=\\s*\"]], \"jos\") then\n        return true, cookies, true\n    end\nend\n\nreturn false\n', '2025-02-23 11:38:45');
INSERT INTO `waf_rules` (`id`, `uid`, `level`, `name`, `phase`, `type`, `description`, `content`, `updated_at`) VALUES (73, 1, 4, 'Tomcat RCE(CVE-2025-24813)', 0, 1, 'CVE-2025-24813是Apache Tomcat部分PUT功能中的一个未经身份验证的远程代码执行漏洞。', 'if waf.method == \"PUT\" and waf.endWith(waf.uri, \"/session\") and waf.reqHeaders[\"Content-Range\"] then\n    return true, waf.form[\"RAW\"], true\nend\n\nreturn false', '2025-03-28 21:21:14');
COMMIT;

-- ----------------------------
-- Table structure for waf_ruleset
-- ----------------------------
DROP TABLE IF EXISTS `waf_ruleset`;
CREATE TABLE `waf_ruleset` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT 1,
  `name` varchar(64) NOT NULL,
  `content` text NOT NULL,
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT;

-- ----------------------------
-- Records of waf_ruleset
-- ----------------------------
BEGIN;
INSERT INTO `waf_ruleset` (`id`, `uid`, `name`, `content`, `updated_at`) VALUES (1, 1, 'Default', '[73,72,70,69,65,64,62,61,60,59,58,56,55,54,53,52,51,50,49,48,47,46,45,44,43,41,29,28,27,25,24,22,21,20,19,18,17,16,15,14,13,12,11,10]', '2025-06-18 20:13:02');
COMMIT;

-- ----------------------------
-- Table structure for waf_sites
-- ----------------------------
DROP TABLE IF EXISTS `waf_sites`;
CREATE TABLE `waf_sites` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `uid` int(11) NOT NULL DEFAULT 1,
  `hosts` text NOT NULL,
  `description` text DEFAULT NULL,
  `mode` tinyint(1) NOT NULL DEFAULT 1,
  `ruleset_id` int(11) NOT NULL,
  `ip_whitelist` text DEFAULT NULL,
  `url_whitelist` text DEFAULT NULL,
  `custom_host` varchar(64) NOT NULL DEFAULT '',
  `deny_page` text DEFAULT NULL,
  `is_websocket` tinyint(1) NOT NULL DEFAULT 0,
  `is_ml` tinyint(1) NOT NULL DEFAULT 0,
  `is_cache` tinyint(1) NOT NULL DEFAULT 0,
  `is_sse` tinyint(1) NOT NULL DEFAULT 0,
  `force_ssl` tinyint(1) NOT NULL DEFAULT 0,
  `ip_source` tinyint(4) NOT NULL DEFAULT 0,
  `ip_order` int(11) NOT NULL DEFAULT 2,
  `ip_header` varchar(64) NOT NULL DEFAULT '',
  `upstream` text NOT NULL,
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT;


-- ----------------------------
-- Table structure for waf_stats
-- ----------------------------
DROP TABLE IF EXISTS `waf_stats`;
CREATE TABLE `waf_stats` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `day` varchar(32) NOT NULL,
  `visits` bigint(20) NOT NULL DEFAULT 0,
  `clients` bigint(20) NOT NULL DEFAULT 0,
  `waf_id` varchar(32) NOT NULL,
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`) USING BTREE,
  KEY `idx_stats` (`day`,`waf_id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT;

-- ----------------------------
-- Records of waf_stats
-- ----------------------------
BEGIN;
INSERT INTO `waf_stats` (`id`, `day`, `visits`, `clients`, `waf_id`, `updated_at`) VALUES (1, '2025-07-13', 108, 15, '1', '2025-07-13 18:55:17');
COMMIT;

-- ----------------------------
-- Table structure for waf_users
-- ----------------------------
DROP TABLE IF EXISTS `waf_users`;
CREATE TABLE `waf_users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `usr` varchar(32) NOT NULL,
  `pwd` varchar(64) NOT NULL,
  `pwd_expiration` int(11) NOT NULL DEFAULT 0,
  `pwd_expired_at` datetime NOT NULL DEFAULT current_timestamp(),
  `fail` int(11) NOT NULL DEFAULT 0,
  `role` tinyint(4) NOT NULL,
  `enable_otp` tinyint(1) NOT NULL DEFAULT 0,
  `otp_url` text NOT NULL,
  `updated_at` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci ROW_FORMAT=COMPACT;

-- ----------------------------
-- Records of waf_users
-- ----------------------------
BEGIN;
INSERT INTO `waf_users` (`id`, `usr`, `pwd`, `pwd_expiration`, `pwd_expired_at`, `fail`, `role`, `enable_otp`, `otp_url`, `updated_at`) VALUES (1, 'admin', '$2a$10$W7PAEPTxyHcRbHg/M8gGbOfByb5pXZBrX.3JLF9UlV0czG5KLFQZC', 0, '2025-07-13 19:13:34', 0, 0, 0, 'otpauth://totp/UUSEC%20WAF:admin?algorithm=SHA1&digits=6&issuer=UUSEC%20WAF&period=30&secret=J7BFOMZX7JOXJSALDG2DHGT6FIWAKNVI', '2025-07-13 19:13:42');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;
